/*
    Copyright 2006-2011 Patrik Jonsson, sunrise@familjenjonsson.org

    This file is part of Sunrise.

    Sunrise is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    Sunrise is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Sunrise.  If not, see <http://www.gnu.org/licenses/>.

*/

/// \file
/// Declaration of the single_lambda_emergence and scatter_emergence classes.

// $Id$


#ifndef __single_lambda_emergence__
#define __single_lambda_emergence__

#include "emergence.h"


namespace mcrx {
  class single_lambda_emergence;
  class scatter_emergence;
}

class binofstream;
class binifstream;

/** Derivation of the emergence class for collecting rays of floats.
    This is used for monochromatic runs. The behavior is identical,
    the only difference is the name of the FITS extensions the data is
    saved in which is taken care of by redefining a few virtual
    functions. Since monochromatic functionality is not included in
    mcrx, it's not really exercised currently. */
class mcrx::single_lambda_emergence: public emergence<T_float> {
public:
  // Constructor takes all the imaging parameters
  single_lambda_emergence(int nt, int np, T_float cd, T_float fov,
			  unsigned int size, bool exclude_south_pole = false,
			  const vec3d& translate_origin=vec3d(),
			  const std::string& type=rectilinear_projection::typestring_) :
    emergence<T_float> (nt, np, cd, fov, size, 
			exclude_south_pole, translate_origin) {};
  single_lambda_emergence
  (const std::vector<std::pair<T_float, T_float> >& cam_pos,
   T_float cd, T_float fov, unsigned int size,
   const vec3d& translate_origin=vec3d(),
   const std::string& type=rectilinear_projection::typestring_) :
    emergence<T_float> (cam_pos, cd, fov, size, translate_origin, type) {};
  single_lambda_emergence (const std::vector<vec3d>& cam_pos, 
			   const std::vector<vec3d>& cam_dir,
			   const std::vector<vec3d>& cam_up,
			   const std::vector<T_float>& fov, 
			   unsigned int size,
			   const vec3d& translate_origin=vec3d(),
			   const std::string& type=rectilinear_projection::typestring_) :
    emergence<T_float> (cam_pos, cam_dir, cam_up, fov, size, 
			translate_origin, type) {};
  single_lambda_emergence (const CCfits::FITS& file);

  // create CAMERAi-SCATTER HDU
  void create_HDU (CCfits::FITS& file, int slices,
		   const T_unit_map& units) const;

  // These functions have to be defined in the derived classes.  They
  // determine the specific names of the HDU's and the comment written.
  /// Determines the specific name of the FITS HDU being written.
  virtual std::string suffix () const = 0;
  /// Determines the comment describing the contents of the FITS HDU
  /// being written.
  virtual std::string comment () const = 0;
  
  // write camera content into a slice
  void write_images (CCfits::FITS&, T_float normalization,
		     int slice) const;
  void load_images (const CCfits::FITS& file, int slice);
  void write_dump (binofstream& file) const;
  void load_dump (binifstream& file);
};


/** The class used for the scattering runs.  A derivation of the
    single_lambda_emergence class, specifying that images are written
    to the CAMERAi-SCATTER HDU's. Apart from this, identical to
    single_lambda_emergence. */
class mcrx::scatter_emergence: public single_lambda_emergence {
public:
  scatter_emergence(int nt, int np, T_float cd, T_float fov,
		    unsigned int size, bool exclude_south_pole= false):
    single_lambda_emergence (nt, np, cd, fov, size, exclude_south_pole) {};
  scatter_emergence
  (const std::vector<std::pair<T_float, T_float> >& cam_pos,
   T_float cd, T_float fov, unsigned int size):
    single_lambda_emergence (cam_pos, cd, fov, size) {};
  scatter_emergence (const std::vector<vec3d>& cam_pos, 
		     const std::vector<vec3d>& cam_dir,
		     const std::vector<vec3d>& cam_up,
		     const std::vector<T_float>& fov, 
		     unsigned int size) :
    single_lambda_emergence (cam_pos, cam_dir, cam_up, fov, size) {};
  scatter_emergence (const CCfits::FITS& file):
    single_lambda_emergence (file) {};

  std::string suffix () const {return "-SCATTER";};
  std::string comment () const {return "This HDU contains a data cube of the images with scattering.  The third dimension is wavelength, for the wavelengths specified in HDU SCATTERING_LAMBDAS";};
};

#endif

